home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / os2 / gigo0714.zip / LISTSERV.CPP < prev    next >
C/C++ Source or Header  |  1996-07-14  |  21KB  |  767 lines

  1. /*
  2.  * LISTSERV
  3.  * 
  4.  * Sample program that takes a GIGO function request file (FUNCTION.REQ), checks
  5.  * it, and then modifies the appropriate .ML files (for mailing lists).
  6.  * 
  7.  * Jason Fesler  December, 1990    jfesler@wmeonlin.sacbbx.com
  8.  */
  9.  
  10. /*
  11.  * Modification History:
  12.  * 
  13.  * Date     By               Description 
  14.  * 2/21/95  David Gibbs      Added recognition of SET & REVIEW command, both commands inform requester that commands are not implemented.
  15.  * 2/3/95   David Gibbs      Changed command recognition from 1 character to 3.
  16.  * 4/25/94  David Gibbs      Added basic activity logging
  17.  * 12/30/95 Jason Fesler     Added in a "confirmation" process
  18.  * 
  19.  */
  20.  
  21. /*
  22.  * For simplicity sake, I include everything, so that I don't have any
  23.  * problems with the compiler knowing what I am talking about.
  24.  */
  25. #include <time.h>
  26. #include <io.h>
  27. #include <fcntl.h>
  28. #include <sys\stat.h>
  29. #include <process.h>
  30. #include <share.h>
  31. #include <stdio.h>
  32. #include <string.h>
  33. #include <stdlib.h>
  34. #include <malloc.h>
  35. #include <conio.h>
  36. #include <ctype.h>
  37. #include <direct.h>
  38. #include <dos.h>
  39. #include <stdarg.h>
  40.  
  41.  
  42. /*
  43.  * Global variables are usually a bad programming practice. However, I don't
  44.  * give a damn.. :-)
  45.  * 
  46.  */
  47.  
  48. extern unsigned int _stklen = 10000;
  49. //Borland style stack declaration,
  50. //ymmv
  51.  
  52. struct headers {
  53.     char            Apparently_To[256];
  54.     char            Apparently_From[256];
  55.     char            To[256];
  56.     char            From[256];
  57.     char            Subject[256];
  58. }               header;
  59.  
  60. char            wholeparm[512] = "";
  61.  
  62. FILE           *infile, *outfile, *file;
  63. int             amihere = 0;
  64. int             amiheremsg = 1;
  65.  
  66. int             useconf = 1;
  67.  
  68. enum commands {
  69.     HELP, INDEX, FAQ, SUBSCRIBE, UNSUBSCRIBE, QUERY, QUIT,
  70.     DISCONNECT, SET, SIG, REVIEW, ADDRESS, CONFIRM, UNKNOWN
  71. };
  72.  
  73. void logproblem(char *cmd, char *parm);
  74.  
  75.  
  76. /*
  77.  * cmpcopy looks to see if string at <source> compares to the string at
  78.  * <token>.  If it does, the parameters after <token> are going to be copied
  79.  * to <dest>.
  80.  */
  81.  
  82.  
  83. void
  84. cmpcopy(char *token, char *source, char *dest)
  85. {
  86.     if (!strncmp(source, token, strlen(token))) {
  87.         source += strlen(token);
  88.         //get past the token itself
  89.             while (*source == ' ')
  90.             source++;
  91.         //get past the spaces
  92.             strcpy(dest, source);
  93.     }
  94. }
  95. /*
  96.  * readheaders reads in the top part of the file until it reaches a newline
  97.  * character.
  98.  * 
  99.  */
  100.  
  101.  
  102. void
  103. readheaders(void)
  104. {
  105.     char            line[1024] = " ";
  106.     memset(&header, 0, sizeof(headers));
  107.     while ((*line) && (!feof(infile))) {
  108.  
  109.         /* remember, GIGO stands for garbage in, garbage out. */
  110.         memset(line, 0, sizeof(line));
  111.         fgets(line, sizeof(line) - 1, infile);
  112.  
  113.         /* fgets includes the line terminator; we need to remove it. */
  114.         if (*line)
  115.             if (line[strlen(line) - 1] == '\n')
  116.                 line[strlen(line) - 1] = 0;
  117.         if (*line)
  118.             if (line[strlen(line) - 1] == '\r')
  119.                 line[strlen(line) - 1] = 0;
  120.         if (!*line)
  121.             continue;    /* We got a blank line, or an eof */
  122.         cmpcopy("Apparently-To:", line, header.Apparently_To);
  123.         cmpcopy("Apparently-From:", line, header.Apparently_From);
  124.         cmpcopy("To:", line, header.To);
  125.         cmpcopy("From:", line, header.From);
  126.         cmpcopy("Subject:", line, header.Subject);
  127.     }
  128. }
  129.  
  130.  
  131. void
  132. show_internal_help()
  133. {
  134.     fprintf(outfile,
  135.           "Simple help instructions for the GIGO listserv processor..\n"
  136.           "----------------------------------------------------------\n"
  137.                 "HELp (or ?)           This help information\n"
  138.                 "CONFIRM number        Submits confirmation number\n"
  139.                 "INDex                 Shows the list of available lists\n"
  140.                  "FAQ listname          Shows the FAQ (info) file for listname\n"
  141.         "SUBscribe listname    Subscribes to listname\n"
  142.         "UNSubscribe listname  Unsubscribes to listname\n"
  143.         "QUEry                 Query the various lists to see which you are on\n"
  144.         "\n"
  145.             "DISconnect            Disconnects from ALL lists on this server\n"
  146.         "\n"
  147.         "Commands may be abbreviated down to 3 characters.\n"
  148.         "\n"
  149.     );
  150. }
  151. /* show_file dumps the file to the reply.  If it does not exist, returns a 1. */
  152.  
  153. int
  154. show_file(char *filename)
  155. {
  156.     //1 = error, 0 = noerror
  157.     FILE * hfile;
  158.     char buf[256];
  159.     int             c;
  160.     hfile = fopen(filename, "rt");
  161.         if (!hfile) {
  162.             sprintf(buf,"Unable to show_file(\"%s\"):  %s",
  163.                     filename,strerror(errno));
  164.             logproblem(buf,"");
  165.             return 1;
  166.         }
  167.     while (!feof(hfile)) {
  168.         c = fgetc(hfile);
  169.         fputc(c, outfile);
  170.     }
  171.     fclose(file);
  172.     return 0;
  173. }
  174. /*
  175.  * Shows the faq file for filename  (filename.FAQ).  If it does not exist, it
  176.  * will print a message to that effect.
  177.  */
  178.  
  179. void
  180. show_faq(char *filename)
  181. {
  182.     char            buf[256];
  183.     sprintf(buf, "%s.faq", filename);
  184.     if (show_file(buf))
  185.         fprintf(outfile, "Sorry, no FAQ file for %s.\n", filename);
  186. }
  187. /*
  188.  * Attempts to dump LISTSERV.HLP to the reply; if that doesn't work, then
  189.  * shows the internal help file instead.
  190.  */
  191.  
  192. void
  193. process_help(void)
  194. {
  195.     if (show_file("LISTSERV.HLP"))
  196.         show_internal_help();
  197. }
  198.  
  199. unsigned long   getcrc(char *buf);
  200.  
  201. void            subscribe(char *filename, int unsub);
  202.  
  203. void
  204. startsubscribe(char *filename)
  205. {
  206.     char            bigbuf[1024];
  207.     FILE            *newfile;
  208.     int             found = 0;
  209.     unsigned long   c;
  210.     time_t          t;
  211.     errno = 0;
  212.     if (!strchr(header.Apparently_From, '@')) {
  213.         fprintf(outfile, "SUB/UNSUB commands require a valid internet style address.\n"
  214.             "Your address appears to be %s  .. \n", header.Apparently_From);
  215.         return;
  216.     }
  217.     errno = 0;
  218.     newfile = fopen("listserv.con", "at");
  219.     if (!newfile)
  220.         newfile = fopen("listserv.con", "wt");
  221.     if (!newfile) {
  222.         fprintf(outfile, "Could not create confirmation file\n", filename);
  223.         return;
  224.     }
  225.     fprintf(outfile, "-------------------------------------------------------------\n");
  226.     fprintf(outfile, "You are in the process of being subscribed to list %s.\n", filename);
  227.     fprintf(outfile, "Following will be a confirmation number; you will need\n");
  228.     fprintf(outfile, "to send back the following to finish subscribing yourself\n");
  229.     fprintf(outfile, "to the list.\n");
  230.     fprintf(outfile, "\nSend back the following:\n\n");
  231.  
  232.     time(&t);
  233.     sprintf(bigbuf, "%s %s %lu", filename, header.Apparently_From, t);
  234.     c = getcrc(bigbuf);
  235.     fprintf(outfile, "  confirm %08lx\n\n", c);
  236.     fprintf(newfile, "%s %08lx\n", bigbuf, c);
  237.     fprintf(outfile, "If you did not send a message to subscribe, you don't have to\n");
  238.     fprintf(outfile, "do anything.  Otherwise, please send this message back as soon\n");
  239.     fprintf(outfile, "as possible, in order to finish subscribing you to list %s.\n", filename);
  240.     fprintf(outfile, "-------------------------------------------------------------\n");
  241.     fclose(newfile);
  242. }
  243.  
  244. void
  245. finishconfirm(char *text)
  246. {
  247.     FILE           *confile;
  248.     char            filename[256] = "";
  249.     char            whofrom[256] = "";
  250.     char            crcval[256] = "";
  251.     char            timestarted[256] = "";
  252.     char            oldfrom[1024] = "";
  253.     char            line[1024];
  254.     char           *p, *p1, *p2, *p3, *p4;
  255.  
  256.     /* text should be just the confirmation number */
  257.  
  258.     if (!text)
  259.         text = "";
  260.     if (text[0] == 0) {
  261.         fprintf(outfile, "You need to specify a confirmation number.\n");
  262.         return;
  263.     }
  264.     fprintf(outfile, "Looking for confirmation number %s\n", text);
  265.     strcpy(oldfrom, header.Apparently_From);
  266.     confile = fopen("listserv.con", "rt");
  267.     if (!confile) {
  268. notfound:
  269.         fprintf(outfile, "You are not currently in the confirmation file.\n");
  270.         fprintf(outfile, "Please send a SUBSCRIBE listname  message to start\n");
  271.         fprintf(outfile, "the subscription process.\n");
  272.         return;
  273.     }
  274.     while (!feof(confile)) {
  275.         memset(line, 0, sizeof(line));
  276.         fgets(line, sizeof(line), confile);
  277.         if (p = strpbrk(line, "\r\n"))
  278.             *p = 0;
  279.         p1 = strtok(line, " ");
  280.         p2 = strtok(NULL, " ");
  281.         p3 = strtok(NULL, " ");
  282.         p4 = strtok(NULL, " ");
  283.         if (!p4)
  284.             continue;
  285.         if (stricmp(p4, text) == 0) {
  286.             strcpy(filename, p1);
  287.             st